package websocket

import (
	"sync"

	"github.com/gogf/gf/v2/container/gset"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/gorilla/websocket"

	"github.com/beherochuling/beesoft_api/app/helper/tool/tool"
)

type Websocket struct {
	FD                          int64          `json:"fd,omitempty"`
	GroupId                     string         `json:"group_id,omitempty"`
	UserId                      int            `json:"user_id,omitempty"`
	Request                     *ghttp.Request `json:"-"`
	websocket                   *ghttp.WebSocket
	mux                         *sync.Mutex
	closed                      bool
	groupIds                    *gset.StrSet
	callbackOnReceivedKeepAlive func(echo bool)
}

func (r *Websocket) onReceivedPing(handle func(echo bool)) {
	r.callbackOnReceivedKeepAlive = handle
}

func (r *Websocket) close() {
	// r.mux.Lock()
	// defer r.mux.Unlock()

	if !r.closed {
		err := r.websocket.Close()
		if err != nil {
			glog.Error(ctx, err)
		}
	}
	r.closed = true
}
func (r *Websocket) Write(data *JsonObject) {
	r.writeMessage(messageTypeJson, data)
}
func (r *Websocket) writeText(data []byte) {
	r.writeMessage(messageTypeText, data)
}
func (r *Websocket) writeMessage(messageType int, v interface{}) {
	if v == nil || r.closed {
		return
	}

	r.mux.Lock()
	defer r.mux.Unlock()

	var bytes []byte
	switch messageType {
	case messageTypeJson:
		if enableContentFilter {
			content := tool.Sensitive.Filter(gconv.String(v))
			bytes = gconv.Bytes(content)
		} else {
			bytes = gjson.MustEncode(v)
		}
	case messageTypeText:
		bytes = gconv.Bytes(v)
	}

	if enableCompression {
		enabled := true
		if len(bytes) <= 32 {
			enabled = false
		}

		r.websocket.EnableWriteCompression(enabled)
	}

	err := r.websocket.WriteMessage(websocket.TextMessage, bytes)
	if err != nil && !r.closed {
		glog.Warning(r.Request.Context(), err)
	}
}

func (r *Websocket) Close() {
	r.close()
}
